using System.Collections;
using System.Linq;
using System.Linq.Expressions;
using Magiq.Support;

namespace Magiq.Delete {
  public class EnumerableSourceFinder {
    public IList FindSourceOf(IEnumerable items) {
      var queryable = items as IQueryable;
      if (queryable != null)
        return FindSourceFromQueryProvider(queryable);

      var collection = items as IList;
      if (collection != null) {
        if (collection.IsFixedSize)
          throw new SourceIsFixedSizeException(queryable);

        return collection;
      }
      var parent = items.Field("source") as IList;

      if (parent == null)
        throw new SourceIsFixedSizeException(queryable);

      return FindSourceOf(parent);
    }

    private IList FindSourceFromQueryProvider(IQueryable queryable) {
      var constant = ConstantFrom(queryable.Expression);

      if (constant == null)
        throw new CannotResolveSourceException(queryable);

      var value = constant.Value.Field("enumerable") as IEnumerable;

      return FindSourceOf(value);
    }

    private static ConstantExpression ConstantFrom(Expression expression) {
      var constant = expression as ConstantExpression;

      if (constant != null)
        return constant;

      var call = expression as MethodCallExpression;

      return call == null ? null : ConstantFrom(call.Arguments[0]);
    }
  }
}